/**
 ********************************************************************************************************
 * @file           key.c
 * @author         Dingzhenghao
 * @brief          按键驱动代码
 * MCU:            CMS8S6990
 * 按键原理：       设置一个1ms定时器定时扫描几个按键的状态，并分别记录按下的持续时间，通过时间可以判断是长按还是
 *                 短按。
 ********************************************************************************************************
 */
#include <CMS8S6990.H>
#include "delay.h"
#include "Key.h"
#include "Nixie.h"
#include "BSP_adc.h"
#include "main.h"

uint8_t key_DoubleShotPresFlag = 0;
uint8_t key_DoubleLongPresFlag = 0;
uint8_t key_Num = 0;

key_struct_t key_list[] = 
{/*按键索引，有效电平*/
	{0,10,5,0,0},
	{1,40,50,0,0},
	{2,50,60,0,0},
	{3,65,75,0,0},
};

// 按键数量
#define KEY_NUM_MAX      (sizeof(key_list)/sizeof(key_list[0]))
#define CONFIRM_TIME     20    // 消抖时间 ms
#define LONG_PRESS_TIME  2000  // 长按时间窗 ms


// 按键配置
#define SHORT_RELEASE_VALID  1 // 0：短按按下时即刻生效，1：短按释放时生效，注意：如果配成0的话，长按的时候就一定会先触发短按
#define LONG_RELEASE_VALID   0 // 0：长按按下时即刻生效，1：长按释放时生效

key_param_t key_param[KEY_NUM_MAX]; // 保存所有按键的状态

/**
  * @brief  按键初始化函数
  * @param  无
  * @retval 无
  */
void key_Init(void)
{
	/* Key1 -- p35 */
	GPIO_SET_MUX_MODE(P35CFG, GPIO_MUX_GPIO);
	GPIO_ENABLE_INPUT(P3TRIS, GPIO_PIN_5);						/* Key1配置为输入模式	*/
	GPIO_ENABLE_UP(P3UP, 5);
	
	/* Key2 -- p21 SLC上拉输入仍未解决，经测试可以下拉输入 */
	GPIO_SET_MUX_MODE(P21CFG, GPIO_MUX_GPIO);
	GPIO_ENABLE_INPUT(P2TRIS, GPIO_PIN_1);						/* Key2配置为输入模式	*/
//	GPIO_ENABLE_OUTPUT(P2TRIS, GPIO_PIN_1);
//	P21 = 1;
	
	GPIO_ENABLE_UP(P2UP, 1);
//	GPIO_DISABLE_UP(P2UP, 1);
//	GPIO_DISABLE_RD(P2UP, 1);
	
//	P21CFG = 0x00;												/* 复用为gpio		    */
//	P2TRIS &= ~0x02;											/* 输入模式				*/
//	P2UP |= 0x02;												/* 上拉模式				*/
	P2DS |= 0x02;												/* 输入输出均可读	    */
	
	/* Key3 -- p22 */
	GPIO_SET_MUX_MODE(P22CFG, GPIO_MUX_GPIO);
	GPIO_ENABLE_INPUT(P2TRIS, GPIO_PIN_2);						/* Key3配置为输入模式	*/
	GPIO_ENABLE_UP(P2UP, 2);
	/* Key4 -- p23 */
	GPIO_SET_MUX_MODE(P23CFG, GPIO_MUX_GPIO);
	GPIO_ENABLE_INPUT(P2TRIS, GPIO_PIN_3);						/* Key4配置为输入模式	*/
	GPIO_ENABLE_UP(P2UP, 3);
}

/**
  * @brief  按键键值获取函数
  * @param  无
  * @retval 无
  */
uint8_t key_GetNum(void)
{
	uint8_t temp = 0;
	temp = key_Num;
	key_Num = 0;
	return temp;
}

/**
  * @brief  读取按键状态函数
  * @param  index:按键索引
  * @retval 按键按下状态
  */
uint8_t read_key_state(uint8_t index)
{
	
	switch (index)
	{
		case 0:
		{
			if(KEY1 == 0)
			{
				return 1;
			}
			else
			{
				return 0;
			}
			break;
		}
		case 1:
		{
			if(KEY2 == 0)
			{
				return 1;
			}
			else
			{
				return 0;
			}
			break;
		}
		case 2:
		{
			if(KEY3 == 0)
			{
				return 1;
			}
			else
			{
				return 0;
			}
			break;
		}
		case 3:
		{
			if(KEY4 == 0)
			{
				return 1;
			}
			else
			{
				return 0;
			}
			break;
		}
		default:
		{
			return 0;
			break;
		}
	}
}



/**
  * @brief  扫描单个按键状态函数（需要按1ms频率扫描）
  * @param  index:按键索引
  * @retval 按键按下状态
  */
uint8_t key_scan(void)
{
    uint8_t key_press;
    uint8_t index;

    for(index = 0; index < KEY_NUM_MAX; index++)
    {// 根据按键列表依次扫描
		
        key_press = read_key_state(index);  // 读取按键状态

        switch (key_param[index].current_state)                                    
        {// 按键状态机
            case KEY_RELEASE:{// 释放状态
                if(key_press)                                                                                                 
                {// 按键按下
                    key_param[index].current_state = KEY_CONFIRM;
                }
                else
                {// 按键松开
                    key_param[index].pressed_time = 0; 
                }
                break;
            }
            case KEY_CONFIRM:{// 按键消抖
                if(key_press)
                {// 按键保持按下
                    if(++key_param[index].pressed_time > CONFIRM_TIME)    // 10ms
                    {// 完成消抖
                        key_param[index].current_state = KEY_SHORT_PRESSED;
					#if (SHORT_RELEASE_VALID == 0)  // 短按按下立马生效
						key_param[index].key_event = EVENT_SHORT_PRESSED;  // 短按事件生效
					#endif
                    }
                }
                else
                {// 按键松开
                    key_param[index].current_state = KEY_RELEASE;
                }
                break;
            }
            case KEY_SHORT_PRESSED:{// 短按
                if(key_press)
                {// 按键保持按下
                    if(++key_param[index].pressed_time > LONG_PRESS_TIME)  // 2000ms
                    {// 长按
                        key_param[index].current_state = KEY_LONG_PRESSED;
					#if (LONG_RELEASE_VALID == 0)  // 长按按下立马生效
						key_param[index].key_event = EVENT_LONG_PRESSED;  // 长按事件生效
					#endif
                    }
                }
                else   
                {// 按键松开
                    key_param[index].current_state = KEY_RELEASE;
				#if (SHORT_RELEASE_VALID == 1)  // 短按释放才生效
					key_param[index].key_event = EVENT_SHORT_PRESSED;  // 短按事件生效
				#endif
                }
                break;
            }
            case KEY_LONG_PRESSED:{// 长按
                if(!key_press)          
                {// 按键松开
					/************/
					key_list[index].key_longflag = 0;
					/************/
                    key_param[index].current_state = KEY_RELEASE;
				#if (LONG_RELEASE_VALID == 1)  // 长按释放才生效
					key_param[index].key_event = EVENT_LONG_PRESSED;  // 长按事件生效
				#endif
                } 
                break;
            }
            default:{
                key_param[index].current_state = KEY_RELEASE;
            }
        }
    }
    return 0;
}

/**
  * @brief  按键处理函数
  * @param  无
  * @retval 无
  */
void key_handle(void)
{
    uint8_t index;
    for (index = 0; index < KEY_NUM_MAX; index++)
    {// 检查有无按键按下
        if(key_param[index].key_event != 0)
        {// 有按键按下
			switch (index)
			{
				case 0:{// 按键1
					if(key_param[index].key_event == EVENT_SHORT_PRESSED)
					{// 短按
						key_list[0].key_shotflag = 1;
						key_Num = 1;
						GucCountMenu = 0;
					}
					else if(key_param[index].key_event == EVENT_LONG_PRESSED)
					{// 长按
					    key_list[0].key_longflag = 1;
						GucCountMenu = 0;
					}
					break;
				}
				case 1:{// 按键2
					if(key_param[index].key_event == EVENT_SHORT_PRESSED)
					{// 短按
						key_list[1].key_shotflag = 1;
						key_Num = 2;
						GucCountMenu = 0;
					}
					else if(key_param[index].key_event == EVENT_LONG_PRESSED)
					{// 长按
						key_list[1].key_longflag = 1;
						GucCountMenu = 0;
					}
					break;
				}
				case 2:{// 按键3
					if(key_param[index].key_event == EVENT_SHORT_PRESSED)
					{// 短按
						key_list[2].key_shotflag = 1;
						key_Num = 3;
						GucCountMenu = 0;
						
					}
					else if(key_param[index].key_event == EVENT_LONG_PRESSED)							/* 开始菜单下长按按键3进入COD选项						 */
					{// 长按
						GucCountMenu = 0;
//						GucSvSetSelect=0;
//						if(MODE == ENG_MENU)
//						{
//							/* 写入FLASH保存 */
//							FLASH_WritePage(FLASH_LAST_PAGE, GusMainMenuBuf);							/* 将设置数据写入FLASH								 	 */
//							/*****************/
//							SetSvNixieBuf(INDEX_SV_MENU);												/* 将主菜单缓存数组值写入SV显示缓存数组			    	 */
//							MODE=MODE_SV_SHOW;															/* 返回开始界面											 */
//						}
//						else if(MODE == MODE_SV_SHOW)
//						{
//							SetSvNixieBuf(INDEX_COD);
//							MODE = COD_MENU;
//						}
						key_list[2].key_longflag = 1;
					}
					break;
				}
				case 3:{// 按键4
					if(key_param[index].key_event == EVENT_SHORT_PRESSED)
					{// 短按
						key_list[3].key_shotflag = 1;
						key_Num = 4;
						GucCountMenu = 0;
					}
					else if(key_param[index].key_event == EVENT_LONG_PRESSED)							/* 开始菜单下按键4长按进入主菜单，并可相互切换			 */
					{// 长按
						GucCountMenu = 0;
						GucMainMenuIndex = 0;
						GucSvSetSelect=0;
						if(MODE == MAIN_MENU)
						{
							PID_Save();
							parametric_limiting();
							/* 写入FLASH保存 */
							FLASH_WritePage(FLASH_LAST_PAGE, GusMainMenuBuf);							/* 将设置数据写入FLASH			 	 					 */
							/*****************/
							SetSvNixieBuf(INDEX_SV_MENU);											/* 将主菜单缓存数组值写入SV显示缓存数组			    	 */
							MODE=MODE_SV_SHOW;															/* 返回开始界面											 */
						}
						else if(MODE == MODE_SV_SHOW)
						{
							MODE=MAIN_MENU;
						}
						key_list[3].key_longflag = 1;
					}
					break;
				}
				default:{
					break;
				}
			}
			key_param[index].key_event = EVENT_NULL;  // 清除该事件
        }
    }
}

/**
  * @brief  按键3和4双长按处理函数
  * @param  无
  * @retval 1：双长按；0：未双长按
  */
uint8_t key_DoubleLongPress(void)
{
	if(key_list[0].key_longflag == 1 && key_list[1].key_longflag == 1)
	{
		key_list[0].key_longflag = 0;
		key_list[1].key_longflag = 0;
		return 1;
	}
	if(key_list[0].key_longflag == 1 && key_list[2].key_longflag == 1)
	{
		key_list[0].key_longflag = 0;
		key_list[2].key_longflag = 0;
		return 2;
	}
	if(key_list[1].key_longflag == 1 && key_list[2].key_longflag == 1)
	{
		key_list[1].key_longflag = 0;
		key_list[2].key_longflag = 0;
		return 3;
	}
	else 
	{
		return 0;
	}
}

void key_DoubleLongState(void)
{
	static xdata uint8_t Last_LongState;
	static xdata uint8_t Now_LongState;
	Last_LongState = Now_LongState;
	Now_LongState = key_DoubleLongPress();
	if(Last_LongState == 0 && Now_LongState == 1)
	{
		GsLongKeyState = 1;
	}
	else if(Last_LongState == 0 && Now_LongState == 2)
	{
		GsLongKeyState = 2;
	}
	else if(Last_LongState == 0 && Now_LongState == 3)
	{
		GsLongKeyState = 3;
	}
	else
	{
		GsLongKeyState = 0;
	}
}

/**
  * @brief  按键1和2双短按处理函数
  * @param  无
  * @retval 1：双短按；0：未双短按
  */
uint8_t key_DoubleShotPress(void)
{
	if(key_list[0].key_shotflag == 1 && key_list[2].key_shotflag == 1)
	{
		key_list[0].key_shotflag = 0;
		key_list[2].key_shotflag = 0;
		return 1;
	}
	else
	{
		return 0;
	}
	
}
